import {
  getCache,
  keys,
  removeCache
} from './store'
import pkg from '../../package'
const axios = require('axios')
// base config
const baseURL = '/api/'
const timeout = 50000
const responseType = 'json'
const headers = {
  'Content-Type': 'application/json;charset=utf-8',
  Accept: 'application/json',
  'client-version': pkg.version
}
const withCredentials = true
const validateStatus = status => status < 500
// 默认异常
const defaultTip = '请检查您的网络连接'
// 系统级异常在生产模式下提示信息
const productErrorTip = 'sorry，系统发生错误！'
const systemErrorCodeStartWith = '1'
const productMode = process.env.NODE_ENV === 'production'
// 回话过期异常编码
const sessionTimeoutCode = '201003'
// act兼容信息
const actMessages = ['Okay', 'Created']

const axiosInstance = axios.create({
  baseURL,
  timeout,
  responseType,
  withCredentials,
  headers,
  validateStatus
})
axiosInstance.interceptors.request.use(
  config => {
    const devid = getCache(keys.devid)
    if (devid) {
      config.headers.devid = devid
    }
    config.headers['client-build'] = devid
    return config
  },
  // eslint-disable-next-line no-undef
  error => Promise.reject(error)
)
axiosInstance.interceptors.response.use(
  response => response,
  // eslint-disable-next-line no-undef
  error => Promise.reject(error)
)

const axiosHandelExcption = async ({
  message = defaultTip,
  status = 500,
  url
}) => {
  // eslint-disable-next-line
  // 非用户异常
  if (status.toString().startsWith(`${systemErrorCodeStartWith}`)) {
    if (productMode === true) {
      message = productErrorTip
    }
  }
  if (productMode === false) {
    message = `${message}(${status}) ${url}`
  }
  // todo 重新登录
  if (sessionTimeoutCode.indexOf(status) > -1) {
    removeCache(keys.user)
    removeCache(keys.shopinfo)
    removeCache(keys.devid)
    removeCache(keys.wxInitStep)
    window.location.reload()
  }
  // eslint-disable-next-line
  return {
    message,
    status
  }
}
const axiosHandel = async (response, url) => {
  if (response.status - 404 > 0) {
    // 404
    return {
      data: null
    }
  } else if (response.status - 300 > 0) {
    // 其他HTTP错误
    return {
      error: await axiosHandelExcption({
        message: response.data.message,
        status: response.status,
        url
      })
    }
  } else if (
    response.data.status ||
    (response.data.message && actMessages.indexOf(response.data.message) ===
      -1)
  ) {
    // 应用内错误
    return {
      error: await axiosHandelExcption({
        message: response.data.message,
        status: response.data.status || response.status,
        url
      })
    }
  } else {
    // 正常数据
    return {
      data: response.data
    }
  }
}
export const get = async (url, params) => {
  let response

  try {
    response = await axiosInstance.get(url, {
      params: params
    })
  } catch (e) {
    throw await axiosHandelExcption({
      msg: e.message,
      url
    })
  }
  const result = await axiosHandel(response, url)
  if (result.error) {
    throw result.error
  } else {
    return result.data
  }
}
export const post = async (url, params) => {
  let response
  try {
    response = await axiosInstance.post(url, params)
  } catch (e) {
    throw await axiosHandelExcption({
      msg: e.message,
      url
    })
  }
  const result = await axiosHandel(response, url)
  if (result.error) {
    throw result.error
  } else {
    return result.data
  }
}
export const put = async (url, params) => {
  let response

  try {
    response = await axiosInstance.put(url, params)
  } catch (e) {
    throw await axiosHandelExcption({
      msg: e.message,
      url
    })
  }
  const result = await axiosHandel(response, url)
  if (result.error) {
    throw result.error
  } else {
    return result.data
  }
}
export const del = async (url, params) => {
  let response

  try {
    response = await axiosInstance.delete(url, {
      params: params
    })
  } catch (e) {
    throw await axiosHandelExcption({
      msg: e.message,
      url
    })
  }
  const result = await axiosHandel(response, url)
  if (result.error) {
    throw result.error
  } else {
    return result.data
  }
}
